package com.ae.shield.common.items.shieldFittings.makers;

import com.ae.shield.common.gui.container.RubbishContainer;
import com.ae.shield.common.inventory.FilterInventory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.inventory.container.SimpleNamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;

public class RubbishShield extends ShieldMakerBase {
    public RubbishShield() {
        super(new Properties(), new ShieldProperty()
                .recovery(0f)
                .cd(1f)
                .maxIntensity(40f)
                .close(1.4f)
                .remote(1.4f)
                .magic(1.6f)
                .other(0f)
                .upperLimit(30f)
                .floorLimit(0f)
                .maxPiles(2)
                .penalty(10f)
                .cost(0));
    }

    @Override
    public void addCtrlInformation(List<ITextComponent> components, ItemStack stack) {
        components.add(new TranslationTextComponent("tooltip.ae.shield.rubbish_shield.tip1").mergeStyle(TextFormatting.GRAY));
        components.add(new TranslationTextComponent("tooltip.ae.shield.rubbish_shield.tip2").mergeStyle(TextFormatting.GRAY));
        components.add(new TranslationTextComponent("tooltip.ae.shield.rubbish_shield.tip3").mergeStyle(TextFormatting.GRAY));
    }

    //-------------------------------------------------------GUI相关---------------------------------------------------------

    @Nullable
    @Override
    public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT nbt) {
        return new Filter(stack);
    }

    private static class Filter implements ICapabilityProvider {
        private final LazyOptional<IItemHandler> opt;

        public Filter(ItemStack stack) {
            opt = LazyOptional.of(() -> new InvWrapper(getInventory(stack)));
        }

        @Nonnull
        @Override
        public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
            return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.orEmpty(cap, opt);
        }
    }

    @Nonnull
    @Override
    public ActionResult<ItemStack> onItemRightClick(@Nonnull World worldIn, PlayerEntity playerIn, @Nonnull Hand handIn) {
        if (!worldIn.isRemote) {
            ItemStack stack = playerIn.getHeldItem(handIn);
            INamedContainerProvider container = new SimpleNamedContainerProvider((id, inventory, player) -> new RubbishContainer(id, inventory, stack), stack.getDisplayName());
            NetworkHooks.openGui((ServerPlayerEntity) playerIn, container, b -> b.writeItemStack(stack));
        }
        return ActionResult.resultSuccess(playerIn.getHeldItem(handIn));
    }

    public static final int SIZE = 9;

    public static FilterInventory getInventory(ItemStack stack) {
        return new FilterInventory(stack, SIZE);
    }

//----------------------------------------------------------------------------------------------------------------------

    /**
     * @param rubbish 用于恢复护盾的垃圾
     * @return 剩余的垃圾
     */
    public ItemStack collectRubbish(ItemStack shield, ItemStack rubbish) {
        if (getInventory(shield).isValid(rubbish)) {
            float min = Math.min(finalMaxIntensity(shield) * (finalMaxPiles(shield) - getPlies(shield) + 1) - getIntensity(shield), rubbish.getCount());
            recoverShield(shield, min, 0);
            return ItemStack.EMPTY;
        }
        return rubbish;
    }

}
